package com.demo.petshop.controller;

import com.demo.petshop.entity.Products;
import com.demo.petshop.mapper.ProductsMapper;
import com.demo.petshop.util.Result;
import com.demo.petshop.util.ZhipuAiUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/ai")
public class AiController {

    @Autowired
    private ProductsMapper productMapper;
    @Autowired
    private ZhipuAiUtil zhipuAiUtil;
    private static final String QUESTION_STR = "question";  // 修改为全大写
    private static final Logger logger = LoggerFactory.getLogger(AiController.class);
    private static final String PRODUCT_STR = "products";
    private static final String ANSWER_STR = "answer";  // 修改为全大写
    private static final String CHAT_LOG_FILE = "chat_log.txt";  // 新增常量

    @PostConstruct
    public void initChatLogFile() {
        try {
            // 1. 使用专用的应用数据目录
            Path dataDir = getSecureDataDirectory();

            // 2. 在安全目录内创建文件
            Path chatLogFile = dataDir.resolve(CHAT_LOG_FILE);

            // 3. 创建文件（如果不存在）
            if (!Files.exists(chatLogFile)) {
                // 确保父目录存在
                Files.createDirectories(chatLogFile.getParent());

                // 创建示例聊天记录文件
                try (BufferedWriter writer = Files.newBufferedWriter(chatLogFile, StandardCharsets.UTF_8)) {
                    writer.write("时间: 2024-01-01 12:00:00\n");
                    writer.write("用户: 这是示例\n");
                    writer.write("AI: 您好！\n");
                    writer.write("类型: text\n");
                    writer.write("------------------------------------------------\n");
                }
                // 记录日志
                logger.info("已创建示例聊天记录文件: {}", chatLogFile);
            }
        } catch (IOException e) {
            // 使用日志框架记录异常
            logger.error("创建聊天记录文件失败", e);
        }
    }

    /**
     * 获取安全的应用数据目录
     */
    private Path getSecureDataDirectory() throws IOException {
        // 使用应用根目录下的固定子目录
        Path appHome = Paths.get("data").toAbsolutePath().normalize();

        // 确保目录存在
        if (!Files.exists(appHome)) {
            Files.createDirectories(appHome);
        }

        return appHome;
    }

    @PostMapping("/ask")
    public Object ask(@RequestBody Map<String, String> body) throws IOException {
        String question = body.get(QUESTION_STR);

        // 判断是否是商品推荐类问题
        if (isProductRecommendationQuestion(question)) {
            return handleProductRecommendation(question);
        }

        // 其它问题走智谱AI
        return handleGeneralQuestion(question);
    }

    /**
     * 判断是否是商品推荐类问题
     */
    private boolean isProductRecommendationQuestion(String question) {
        if (question == null) return false;

        // 定义关键词列表
        List<String> keywords = Arrays.asList(
                "推荐", "买", "商品", "适合", "食品", "用品",
                "狗", "猫", "水族", "医疗", "保健", "美容"
        );

        // 检查问题中是否包含任一关键词
        return keywords.stream().anyMatch(question::contains);
    }

    /**
     * 处理商品推荐类问题
     */
    private Object handleProductRecommendation(String question) throws IOException {
        Map<String, Object> result = new HashMap<>();
        String productType = PRODUCT_STR;
        result.put("type", productType);

        // 识别动物类型
        String animalKeyword = identifyAnimalType(question);

        // 识别商品分类
        Integer productTypeCategoryId = identifyProductCategory(question);

        // 获取动物分类ID
        Integer animalCategoryId = mapAnimalToCategory(animalKeyword);

        // 查询匹配的商品
        List<Products> productList = queryProducts(productTypeCategoryId, animalKeyword, animalCategoryId);

        // 格式化商品数据
        List<Map<String, Object>> formattedProducts = formatProductsData(productList);
        result.put(productType, formattedProducts);

        // 保存聊天记录
        saveProductRecommendationLog(question, formattedProducts);

        return Result.success(result);
    }

    /**
     * 识别问题中的动物类型
     */
    private String identifyAnimalType(String question) {
        if (question.contains("狗")) return "狗";
        if (question.contains("猫")) return "猫";
        if (question.contains("水族")) return "水族";
        return null;
    }

    /**
     * 识别问题中的商品分类
     */
    private Integer identifyProductCategory(String question) {
        if (question.contains("食品") || question.contains("粮") || question.contains("饲料")) {
            return 4;
        } else if (question.contains("用品")) {
            return 5;
        } else if (question.contains("医疗") || question.contains("保健")) {
            return 6;
        } else if (question.contains("美容")) {
            return 7;
        }
        return null;
    }

    /**
     * 将动物类型映射到分类ID
     */
    private Integer mapAnimalToCategory(String animalKeyword) {
        if (animalKeyword == null) return null;

        return switch (animalKeyword) {
            case "狗" -> 1;
            case "猫" -> 2;
            case "水族" -> 3;
            default -> null;
        };
    }

    /**
     * 查询匹配的商品
     */
    private List<Products> queryProducts(Integer productTypeCategoryId, String animalKeyword, Integer animalCategoryId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        List<Products> productList;

        // 优先使用商品类型进行查询
        if (productTypeCategoryId != null) {
            queryWrapper.eq(Products::getCategoryId, productTypeCategoryId);
            productList = productMapper.selectListByQuery(queryWrapper);

            // 如果同时有动物关键词，进行二次筛选
            if (animalKeyword != null) {
                List<Products> filteredList = filterProductsByAnimal(productList, animalKeyword);
                if (!filteredList.isEmpty()) {
                    return filteredList;
                }
            }
            return productList;
        } else if (animalCategoryId != null) {
            // 仅有动物关键词
            queryWrapper.eq(Products::getCategoryId, animalCategoryId);
            return productMapper.selectListByQuery(queryWrapper);
        } else {
            // 通用推荐
            return productMapper.selectAll();
        }
    }

    /**
     * 根据动物关键词筛选商品
     */
    private List<Products> filterProductsByAnimal(List<Products> products, String animalKeyword) {
        return products.stream()
                .filter(p -> p.getName().contains(animalKeyword) ||
                        (p.getDescription() != null && p.getDescription().contains(animalKeyword)))
                .collect(Collectors.toList());
    }

    /**
     * 格式化商品数据
     */
    private List<Map<String, Object>> formatProductsData(List<Products> productList) {
        return productList.stream()
                .map(product -> {
                    Map<String, Object> productMap = new HashMap<>();
                    productMap.put("id", product.getProductId());
                    productMap.put("name", product.getName());
                    productMap.put("price", product.getSalePrice());
                    productMap.put("link", "http://localhost:8080/#/product/" + product.getProductId());
                    return productMap;
                })
                .collect(Collectors.toList());
    }

    /**
     * 保存商品推荐的聊天记录
     */
    private void saveProductRecommendationLog(String question, List<Map<String, Object>> products) throws IOException {
        try {
            ObjectMapper mapper = new ObjectMapper();
            String productsJson = mapper.writeValueAsString(products);
            saveChatLog(question, "为您推荐以下商品：", PRODUCT_STR, productsJson);
        } catch (Exception e) {
            saveChatLog(question, "商品推荐: " + products, PRODUCT_STR, products.toString());
        }
    }

    /**
     * 处理一般性问题
     */
    private Object handleGeneralQuestion(String question) throws IOException {
        Map<String, Object> result = new HashMap<>();
        String aiAnswer = zhipuAiUtil.chatWithZhipu(question);
        result.put("type", "text");
        result.put(ANSWER_STR, aiAnswer);

        // 保存聊天记录到文件
        saveChatLog(question, aiAnswer);
        return Result.success(result);
    }

    @GetMapping("/history")
    public Object getHistory() {
        Map<String, Object> result = new HashMap<>();
        List<Map<String, Object>> records = new ArrayList<>();

        try {
            // 1. 获取聊天日志文件
            Path chatLogFile = getSecureDataDirectory().resolve(CHAT_LOG_FILE);

            // 2. 读取并解析聊天记录
            if (Files.exists(chatLogFile)) {
                records = parseChatLogFile(chatLogFile);
            } else {
                logger.warn("聊天记录文件不存在: {}", chatLogFile);
            }
        } catch (IOException e) {
            logger.error("读取聊天记录失败", e);
        }

        result.put("records", records);
        return Result.success(result);
    }

    /**
     * 解析聊天日志文件
     */
    private List<Map<String, Object>> parseChatLogFile(Path chatLogFile) throws IOException {
        List<Map<String, Object>> records = new ArrayList<>();

        // 读取文件内容
        List<String> lines = Files.readAllLines(chatLogFile, StandardCharsets.UTF_8);

        // 解析对话内容
        ChatEntry currentEntry = new ChatEntry();

        for (String line : lines) {
            line = line.trim();

            if (isDialogueSeparator(line)) {
                // 保存当前对话并重置
                saveAndResetEntry(records, currentEntry);
            } else {
                // 解析当前行
                parseDialogueLine(line, currentEntry);
            }
        }

        // 处理最后一个对话（如果没有分隔线结尾）
        if (currentEntry.isComplete()) {
            addEntryToRecords(records, currentEntry);
        }

        Collections.reverse(records);

        // 添加日志级别检查
        if (logger.isInfoEnabled()) {
            logger.info("总共解析出 {} 条记录", records.size());
        }

        return records;
    }

    /**
     * 判断是否是对话分隔符
     */
    private boolean isDialogueSeparator(String line) {
        return "------------------------------------------------".equals(line);
    }

    /**
     * 解析对话中的一行内容
     */
    private void parseDialogueLine(String line, ChatEntry entry) {
        // 提取前缀和值
        String[] parts = extractPrefixAndValue(line);
        if (parts == null) return;

        String prefix = parts[0];
        String value = parts[1];

        // 根据前缀处理
        switch (prefix) {
            case "时间":
                entry.time = value;
                logDebug("找到时间: {}", value);
                break;
            case "用户":
                entry.question = value;
                logDebug("找到用户问题: {}", value);
                break;
            case "AI":
                entry.answer = value;
                logDebug("找到AI回答: {}", value);
                break;
            case "类型":
                entry.type = value;
                logDebug("找到类型: {}", value);
                break;
            case "数据":
                entry.data = value;
                logDebug("找到数据: {}", value);
                break;
            default:
                // 处理未知前缀
                if (logger.isDebugEnabled()) {
                    logger.debug("忽略未知前缀: {} 值: {}", prefix, value);
                }
                break;
        }
    }

    /**
     * 从行中提取前缀和值
     * @return 包含前缀和值的数组，如果不匹配则返回null
     */
    private String[] extractPrefixAndValue(String line) {
        int colonIndex = line.indexOf(": ");
        if (colonIndex > 0) {
            String prefix = line.substring(0, colonIndex);
            String value = line.substring(colonIndex + 2).trim();
            return new String[]{prefix, value};
        }
        return null;
    }

    /**
     * 带日志级别检查的调试日志
     */
    private void logDebug(String message, Object... args) {
        if (logger.isDebugEnabled()) {
            logger.debug(message, args);
        }
    }

    /**
     * 保存当前对话并重置
     */
    private void saveAndResetEntry(List<Map<String, Object>> records, ChatEntry entry) {
        if (entry.isComplete()) {
            addEntryToRecords(records, entry);

            // 添加日志级别检查
            if (logger.isDebugEnabled()) {
                logger.debug("保存对话记录(分隔线): {} -> {}", entry.question, entry.answer);
            }
        }
        entry.reset();
    }

    /**
     * 将对话条目添加到记录列表
     */
    private void addEntryToRecords(List<Map<String, Object>> records, ChatEntry entry) {
        Map<String, Object> recordMap = new HashMap<>();
        recordMap.put(QUESTION_STR, entry.question);
        recordMap.put(ANSWER_STR, entry.answer);
        recordMap.put("time", entry.time != null ? entry.time : "未知时间");
        recordMap.put("type", entry.type);
        if (entry.data != null) {
            recordMap.put("data", entry.data);
        }
        records.add(recordMap);
    }

    /**
     * 聊天记录条目类
     */
    private static class ChatEntry {
        String question = null;
        String answer = null;
        String time = null;
        String type = "text";
        String data = null;

        boolean isComplete() {
            return question != null && answer != null;
        }

        void reset() {
            question = null;
            answer = null;
            time = null;
            type = "text";
            data = null;
        }
    }

    private void saveChatLog(String question, String answer, String type, Object data) {
        try {
            // 1. 使用安全的应用数据目录
            Path chatLogFile = getSecureDataDirectory().resolve(CHAT_LOG_FILE);

            // 2. 使用BufferedWriter写入文件
            try (BufferedWriter writer = Files.newBufferedWriter(
                    chatLogFile, StandardCharsets.UTF_8,
                    StandardOpenOption.CREATE, StandardOpenOption.APPEND)) {

                // 添加时间戳
                String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                writer.write("时间: " + timestamp + "\n");
                writer.write("用户: " + question + "\n");
                writer.write("AI: " + answer + "\n");
                writer.write("类型: " + type + "\n");
                if (data != null) {
                    writer.write("数据: " + data + "\n");
                }
                writer.write("------------------------------------------------\n");
            }
        } catch (IOException e) {
            // 记录异常，而不是忽略
            logger.error("保存聊天记录失败", e);
        }
    }

    /**
     * 简化版本的saveChatLog方法，用于纯文本回答
     */
    private void saveChatLog(String question, String answer) {
        saveChatLog(question, answer, "text", null);
    }
}
